﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using OneCaps.Core.Entity;

namespace OneCaps.DB
{
    /// <summary>
    /// 应用程序数据上下文
    /// </summary>
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
        }

        /// <summary>
        /// 车辆表
        /// </summary>
        public DbSet<Vehicle> Vehicles { get; set; }

        /// <summary>
        /// 车位表
        /// </summary>
        public DbSet<ParkingSpace> ParkingSpaces { get; set; }

        /// <summary>
        /// 停车记录表
        /// </summary>
        public DbSet<ParkingRecord> ParkingRecords { get; set; }

        /// <summary>
        /// 收费规则表
        /// </summary>
        public DbSet<BillingRule> BillingRules { get; set; }

        /// <summary>
        /// 特殊时段规则表
        /// </summary>
        public DbSet<SpecialTimeRule> SpecialTimeRules { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            // 配置车辆实体
            modelBuilder.Entity<Vehicle>(entity =>
            {
                entity.HasKey(e => e.Id);
                entity.Property(e => e.LicensePlate).IsRequired().HasMaxLength(20);
                entity.Property(e => e.Brand).HasMaxLength(50);
                entity.Property(e => e.Model).HasMaxLength(50);
                entity.Property(e => e.Color).HasMaxLength(20);
                entity.Property(e => e.OwnerName).HasMaxLength(50);
                entity.Property(e => e.OwnerPhone).HasMaxLength(20);
                
                // 车牌号唯一索引
                entity.HasIndex(e => e.LicensePlate).IsUnique();
                
                // 与停车记录的关系
                entity.HasMany(e => e.ParkingRecords)
                      .WithOne(e => e.Vehicle)
                      .HasForeignKey(e => e.VehicleId)
                      .OnDelete(DeleteBehavior.Restrict);
            });

            // 配置车位实体
            modelBuilder.Entity<ParkingSpace>(entity =>
            {
                entity.HasKey(e => e.Id);
                entity.Property(e => e.SpaceNumber).IsRequired().HasMaxLength(20);
                entity.Property(e => e.Area).IsRequired().HasMaxLength(50);
                entity.Property(e => e.Dimensions).HasMaxLength(20);
                entity.Property(e => e.Remarks).HasMaxLength(200);
                
                // 车位编号唯一索引
                entity.HasIndex(e => e.SpaceNumber).IsUnique();
                
                // 与停车记录的关系
                entity.HasMany(e => e.ParkingRecords)
                      .WithOne(e => e.ParkingSpace)
                      .HasForeignKey(e => e.ParkingSpaceId)
                      .OnDelete(DeleteBehavior.Restrict);
            });

            // 配置停车记录实体
            modelBuilder.Entity<ParkingRecord>(entity =>
            {
                entity.HasKey(e => e.Id);
                entity.Property(e => e.LicensePlate).IsRequired().HasMaxLength(20);
                entity.Property(e => e.SpaceNumber).IsRequired().HasMaxLength(20);
                entity.Property(e => e.EntryPhotoPath).HasMaxLength(500);
                entity.Property(e => e.ExitPhotoPath).HasMaxLength(500);
                entity.Property(e => e.EntryOperator).HasMaxLength(50);
                entity.Property(e => e.ExitOperator).HasMaxLength(50);
                entity.Property(e => e.EntryGateNumber).HasMaxLength(20);
                entity.Property(e => e.ExitGateNumber).HasMaxLength(20);
                entity.Property(e => e.TransactionId).HasMaxLength(100);
                entity.Property(e => e.Remarks).HasMaxLength(500);
                
                // 与收费规则的关系
                entity.HasOne(e => e.BillingRule)
                      .WithMany()
                      .HasForeignKey(e => e.BillingRuleId)
                      .OnDelete(DeleteBehavior.SetNull);
            });

            // 配置收费规则实体
            modelBuilder.Entity<BillingRule>(entity =>
            {
                entity.HasKey(e => e.Id);
                entity.Property(e => e.Name).IsRequired().HasMaxLength(100);
                entity.Property(e => e.Description).HasMaxLength(500);
                
                // 与特殊时段规则的关系
                entity.HasMany(e => e.SpecialTimeRules)
                      .WithOne(e => e.BillingRule)
                      .HasForeignKey(e => e.BillingRuleId)
                      .OnDelete(DeleteBehavior.Cascade);
            });

            // 配置特殊时段规则实体
            modelBuilder.Entity<SpecialTimeRule>(entity =>
            {
                entity.HasKey(e => e.Id);
            });

            // 配置全局查询过滤器
            modelBuilder.Entity<Vehicle>().HasQueryFilter(e => !e.IsDeleted);
            modelBuilder.Entity<ParkingSpace>().HasQueryFilter(e => !e.IsDeleted);
            modelBuilder.Entity<ParkingRecord>().HasQueryFilter(e => !e.IsDeleted);
            modelBuilder.Entity<BillingRule>().HasQueryFilter(e => !e.IsDeleted);
            modelBuilder.Entity<SpecialTimeRule>().HasQueryFilter(e => !e.IsDeleted);
        }

        public override int SaveChanges()
        {
            UpdateTimestamps();
            return base.SaveChanges();
        }

        public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            UpdateTimestamps();
            return base.SaveChangesAsync(cancellationToken);
        }

        /// <summary>
        /// 更新时间戳
        /// </summary>
        private void UpdateTimestamps()
        {
            var entries = ChangeTracker.Entries()
                .Where(e => e.Entity is BaseEntity<int> && (e.State == EntityState.Added || e.State == EntityState.Modified));

            foreach (var entry in entries)
            {
                var entity = (BaseEntity<int>)entry.Entity;

                if (entry.State == EntityState.Added)
                {
                    entity.CreateTime = DateTime.Now;
                }

                entity.UpdateTime = DateTime.Now;
            }
        }
    }

    // Startup.cs
//    services.AddDbContext<AppDbContext>(options =>
//    options.UseSqlServer(Configuration.GetConnectionString("Default")));

//services.AddScoped(typeof(IRepository<,>), typeof(EFCoreRepository<,>));
}
